package com.zlcx.tz.live.service;

import com.zlcx.tz.live.domain.TimeLearnRoomDO;
import com.zlcx.tz.live.domain.TimeLearnRoomSeatsDO;
import com.zlcx.tz.live.domain.TimeLearnRoomUsersDO;
import com.zlcx.tz.live.exception.RoomSeatException;
import com.zlcx.tz.live.exception.RoomSeatUsedException;
import com.zlcx.tz.live.exception.UnRoomUserException;
import com.zlcx.tz.live.exception.UserTimeLearningException;
import com.zlcx.tz.live.processor.JoinRoomPostProcessor;
import com.zlcx.tz.live.processor.QuitRoomPostProcessor;
import com.zlcx.tz.live.processor.SitUpPostProcessor;
import com.zlcx.tz.live.processor.TakeSeatPostProcessor;
import com.zlcx.tz.live.vo.TimeLearnRoomSeatsVO;
import com.zlcx.tz.live.vo.TimeLearnRoomVO;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.util.List;

/**
 * @author: anjl
 * @data: 2020-09-27
 **/
public interface TimeLearnRoomService {
    /**
     * 保存/更新
     *
     * @param room room
     */
    TimeLearnRoomDO save(TimeLearnRoomDO room);

    /**
     * 加入房间
     * 扩展接口
     *
     * @param roomId roomId
     * @see JoinRoomPostProcessor
     */
    void joinRoom(Long roomId, Long userId) throws UserTimeLearningException, UnRoomUserException;

    /**
     * 退出房间
     * 扩展接口
     *
     * @param roomId roomId
     * @see QuitRoomPostProcessor
     */
    void quitRoom(Long roomId, Long userId) throws UnRoomUserException, UserTimeLearningException;

    /**
     * 入座
     * 扩展接口
     *
     * @param seatId seatId
     * @param userId userId
     * @see TakeSeatPostProcessor
     */
    TimeLearnRoomSeatsVO takeSeat(Long seatId, Long userId, Long contentId, String content, Integer minute, Integer useOtherApps) throws RoomSeatException, UnRoomUserException, RoomSeatUsedException, UserTimeLearningException;

    /**
     * 离开座位
     * 扩展接口
     *
     * @param roomId roomId
     * @param userId userId
     * @see SitUpPostProcessor
     */
    void sitUpAndQuit(Long roomId, Long userId) throws RoomSeatException;

    /**
     * 查询并锁定数据
     *
     * @param roomId roomId
     */
    TimeLearnRoomDO lockRoom(Long roomId);

    /**
     * 房间空闲座位数
     *
     * @param roomId roomId
     */
    Integer usedSeatsNum(Long roomId);

    /**
     * 心跳-心跳通过将房间信息维护在redis中，来检测房间内用户是否还真实存在
     * 如果心跳超时时间过长，用户没有在计时中，则将用户移除房间
     * 用户回到房间页面，重新心跳后，提示房间是否还存在如果，不存在，则重新调用进入房间接口，进入房间
     *
     * @param roomId roomId
     * @param userId userId
     */
    void heart(Long roomId, Long userId) throws UnRoomUserException;

    /**
     * 获取计时自习室详细信息
     *
     * @param roomId roomId
     */
    TimeLearnRoomVO detail(Long roomId);

    /**
     * 计时房间列表
     */
    List<TimeLearnRoomVO> list(Integer type);

    /**
     * 用户房间内信息
     */
    TimeLearnRoomSeatsDO getTimeLearnRoomSeatsByUserId(Long userId);

    /**
     * 查询计时自习室房间内的用户
     */
    Page<TimeLearnRoomUsersDO> findUsers(Long roomId, Pageable page);

    /**
     * 查询所有的房间
     */
    List<TimeLearnRoomDO> allRooms();

    /**
     * 根据用户id查询用户房间信息
     */
    TimeLearnRoomUsersDO findByUserId(Long userId);

    /**
     *  查询房间内所有的座位
     * @param roomId roomId
     */
    List<TimeLearnRoomSeatsVO> allSeats(Long roomId);

    /**
     * 查询所有房间数据（缓存）
     */
    TimeLearnRoomDO getSimpleRoomInfo(Long id);

    /**
     * 查询所有学习时间过期的用户
     */
    List<TimeLearnRoomSeatsVO> findExpireUsers();

    /**
     * 总学习人数
     */
    Integer sumUsedSeatsNum();
}
